# coding=utf8
__author__ = 'lijian'

import time
import datetime
import threading
import logging
import random
import manager
import action
import monitor
import event
import config
from protocol.term import *
import rtu.manager

_pollCurIndex = 0

_todayLampPlanTasks = []
_todayGroupPlanTask = []


_todayRtuPlanTaSK = []

_monitor = monitor.Monitor.GetInstance()


def isPowerOn():
    # now = datetime.datetime.now()
    # if 7 < now.hour < 18:
    #     return False
    # else:
    #     return True

    return True


def configTerm(term):
    logging.info("config term:%r" % (term.uid,))

    data = []
    data.append(0x20)  # ctrl
    data.append(0)  # 上电报警时间
    data.append(len(term.holders))  # 灯头数量

    for h in term.holders:
        data.append(1)  # 子网号
        data.append(h.holderNo)  # 节点号
        data.append(1)  # 调光类型
        data.extend([0, 0, 0, 0x14])  # 是否上电后调光

    packet = Packet(ctrl.UNICAST_COMM, data, term.uid)
    response = _monitor.send(packet=packet, retry=True)
    if response:
        logging.info("%r config successful" % (term.uid,))
        term.sync = True
        manager.saveLamps()
    else:
        logging.info("%r config fail" % (term.uid,))


def queryTerm(term):
    data = [0x64]
    packet = Packet(ctrl.UNI_CAST, data, term.uid)
    response = _monitor.send(packet=packet, retry=True)
    if response:
        for holder in term.holders:
            holder.insertHistory()
            event.checkLampException(holder)
        term.poolSuccess = True
    else:
        term.poolSuccess = False


def querySnapshot(term):
    pass


def fixDeadNodeData():
    logging.info("fix dead node data")
    holders = manager.getAllHolder()
    for holder in holders:
        if holder.ownerTerm.poolSuccess:
            continue

        logging.debug("fix %r data" % (holder.uid,))
        template = findTemplateHolder(holder)
        if template:
            holder.fixData(template)
        else:
            logging.warn("not find template for fix date")


def findTemplateHolder(deadHolder):
    fineHolders = []
    allHolders = manager.getAllHolder()
    for holder in allHolders:
        # if holder.ownerTerm.poolSuccess and holder.lineNo == deadHolder.lineNo:
        if holder.ownerTerm.poolSuccess:
            fineHolders.append(holder)

    size = len(fineHolders)
    if size == 0:
        return None

    i = random.randint(0, len(fineHolders))
    template = allHolders[i]
    return template


def poll():
    global _pollCurIndex

    terms = manager.getAllTerms()
    if len(terms) == 0:
        return

    if _pollCurIndex >= len(manager.getAllTerms()):
        _pollCurIndex = 0
        fixDeadNodeData()

    term = terms[_pollCurIndex]
    _pollCurIndex += 1

    if not term.sync:
        configTerm(term)
    else:
        queryTerm(term)

    time.sleep(random.randint(1,5))


def initTodayTempSchedule():
    global _todayLampPlanTasks, _todayGroupPlanTask, _todayRtuPlanTaSK
    now = datetime.datetime.now()

    _todayLampPlanTasks = manager.findLampPlanTask(now.year, now.month, now.day)
    _todayGroupPlanTask = manager.findGroupPlanTask(now.year, now.month, now.day)
    _todayRtuPlanTaSK = manager.findRtuPlanTask(now.year, now.month, now.day)


def checkPlanTask():
    now = time.time()
    isChange = False

    for planTask in _todayLampPlanTasks:
        timestamp = time.mktime(planTask.planTime.timetuple())

        if now >= timestamp and not planTask.finished:
            logging.info("execute lamp panel task,time:%s, lampNo:%d,value:%d" % (
                planTask.planTime.strftime("%Y-%m-%d %H:%M:%S"), planTask.holderNo, planTask.optType))

            rtn = action.pointCtrl(planTask.holderNo, planTask.optType, planTask.level)
            if rtn:
                planTask.finished = True
                isChange = True

    for planTask in _todayGroupPlanTask:
        timestamp = time.mktime(planTask.planTime.timetuple())
        if now >= timestamp and not planTask.finished:
            logging.info("execute lamp panel task,time:%s, lampNo:%d,value:%d" % (
                planTask.planTime.strftime("%Y-%m-%d %H:%M:%S"), 1, 1))

            rtn = action.groupCtrl(planTask.groupNo, planTask.optType, planTask.level)
            if rtn:
                planTask.finished = True
                isChange = True

    for planTask in _todayRtuPlanTaSK:
        timestamp = time.mktime(planTask.planTime.timetuple())
        if now >= timestamp and not planTask.finished:
            logging.info(
                "execute rtu panel task,time:%s, value:%d" % (planTask.planTime.strftime("%Y-%m-%d %H:%M:%S"), 1))

            import rtu.action

            type = planTask.optType

            level = 0
            if type == 0:
                level = 3
            elif type == 1:
                level = 0

            rtu.action.ctrlToLevel(level)

    if isChange:
        manager.savePlanTask()


def autoTask():
    initTodayTempSchedule()
    while True:
        curTime = time.time()
        # 有主站操作时，不进行自动轮询
        if curTime - _monitor.getSuspendTime() <= 30:
            time.sleep(1)
            continue

        if rtu.manager.isPollTime():
            terms = manager.getAllTerms()
            if len(terms) == 0:
                pass
            else:
                poll()

        checkPlanTask()


        # if not isPowerOn():
        #     clearHolderData()

        time.sleep(1)

def clearHolderData():
    allHolders=manager.getAllHolder()
    for holder in allHolders:
        holder.clearData()

def start():
    th = threading.Thread(target=autoTask)
    th.setDaemon(True)
    th.start()